package com.halixun.d2app.ui.fragment;


import android.app.Activity;
import android.content.Intent;
import android.graphics.Rect;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.google.gson.Gson;
import com.halixun.d2app.R;
import com.halixun.d2app.adapter.PrintListAdapter;
import com.halixun.d2app.app.MyApplication;
import com.halixun.d2app.base.BaseFragment;
import com.halixun.d2app.base.BasePrintInfo;
import com.halixun.d2app.bean.print.BlueToothPrintInfo;
import com.halixun.d2app.bean.print.NetPrintInfo;
import com.halixun.d2app.bean.print.UsbPrintInfo;
import com.halixun.d2app.dialog.AddNetPrintDialogFragment;
import com.halixun.d2app.dialog.ReminderFragment;
import com.halixun.d2app.printer.USBPrinter;
import com.halixun.d2app.ui.PrintSettingActivity;
import com.halixun.d2app.utils.PrintReceiptsUtil;
import com.halixun.d2app.utils.ToastUtils;

import java.util.ArrayList;
import java.util.List;


/**
 * A simple {@link Fragment} subclass.
 */
public class OtherFragment extends BaseFragment implements View.OnClickListener, USBPrinter.UsbPrintListener, PrintListAdapter.PrintListListener {

    private static final String KEY_TAG = "key_tag";

    private TextView addNetPrint;

    private AddNetPrintDialogFragment dialogFragment;

    private USBPrinter usbPrinter;

    private int clickPosition = -1;

    private List<NetPrintInfo> mNetPrintInfos;

    private List<UsbPrintInfo> mUsbPrintInfos;

    private PrintListAdapter mUsbAdapter;

    private PrintListAdapter mNetAdapter;

    private RecyclerView usbRecyclerView, netRecyclerView;

    private ReminderFragment reminderFragment;

    public static BaseFragment getInstance(String tag) {
        OtherFragment f = new OtherFragment();
        Bundle params = new Bundle();
        params.putString(KEY_TAG, tag);
        f.setArguments(params);
        return f;
    }

    private String tag;

    public OtherFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tag = getArguments().getString(KEY_TAG);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_other, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        usbPrinter = USBPrinter.getInstance();
        if (!usbPrinter.getInitState()) {
            USBPrinter.initPrinter();
        }
        super.onViewCreated(view, savedInstanceState);
        setAdapter();
        getData();
    }

    private void getData() {
        List<NetPrintInfo> netPrintInfos = PrintReceiptsUtil.getNetPrint();
        if (netPrintInfos != null) {
            mNetPrintInfos.addAll(netPrintInfos);
            mNetAdapter.notifyDataSetChanged();
        }
        mUsbPrintInfos.addAll(MyApplication.getUsbPrintList());
        mUsbAdapter.notifyDataSetChanged();
    }

    @Override
    protected void initView() {
        addNetPrint = mRootView.findViewById(R.id.addNetPrint);
        usbRecyclerView = mRootView.findViewById(R.id.usbRecyclerView);
        netRecyclerView = mRootView.findViewById(R.id.netRecyclerView);
    }

    @Override
    protected void setListeners() {
        addNetPrint.setOnClickListener(this);
        usbPrinter.setUsbPrintListener(this);
    }

    private void setAdapter() {
        mNetPrintInfos = new ArrayList<>();
        mUsbPrintInfos = new ArrayList<>();
        mUsbAdapter = new PrintListAdapter(mUsbPrintInfos);
        mNetAdapter = new PrintListAdapter(mNetPrintInfos);
        mUsbAdapter.setPrintListListener(this);
        mNetAdapter.setPrintListListener(this);
        usbRecyclerView.setAdapter(mUsbAdapter);
        netRecyclerView.setAdapter(mNetAdapter);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.addNetPrint:
                if (dialogFragment == null) {
                    dialogFragment = new AddNetPrintDialogFragment();
                    dialogFragment.setOnAddNetPrintDialogListener((ip, port) -> {
                        boolean isHas = false;
                        for (NetPrintInfo info : mNetPrintInfos) {
                            if (ip.equals(info.ip) && port == info.port) {
                                isHas = true;
                            }
                        }
                        if (isHas) {
                            ToastUtils.showCenterToast("已添加此打印机");
                            return;
                        } else {
                            NetPrintInfo info = new NetPrintInfo();
                            info.isPrint = true;
                            info.port = port;
                            info.ip = ip;
                            PrintReceiptsUtil.setNetPrint(info);
                            mNetPrintInfos.add(info);
                            mNetAdapter.notifyItemInserted(mNetPrintInfos.size() - 1);
                            ToastUtils.showCenterToast("网络打印机添加成功");
                        }
                    });
                }
                dialogFragment.show(getChildFragmentManager(), "addNetPrintDialogFragment");
                break;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        usbPrinter.setUsbPrintListener(null);
    }

    @Override
    public void onAddUsbPrint(UsbPrintInfo usbDevice) {
        int dex = MyApplication.getUsbPrintList().indexOf(usbDevice);
        mUsbPrintInfos.add(dex,usbDevice);
        mUsbAdapter.notifyItemInserted(dex);
    }

    @Override
    public void onRemoveUsbPrint(UsbPrintInfo usbDevice) {
        if (mUsbPrintInfos.contains(usbDevice)){
            int index = mUsbPrintInfos.indexOf(usbDevice);
            mUsbPrintInfos.remove(index);
            mUsbAdapter.notifyItemRemoved(index);
        }
    }

    @Override
    public void onPrintListItemClick(int position, BasePrintInfo data) {
        if (data == null || position == -1) return;
        this.clickPosition = position;
        BasePrintInfo info;
        if (data.type == BasePrintInfo.USB_PRINT) {
            info = mUsbPrintInfos.get(clickPosition);
        } else {
            info = mNetPrintInfos.get(clickPosition);
        }
        Intent intent = new Intent();
        intent.setClass(mContext, PrintSettingActivity.class);
        intent.putExtra(PrintSettingActivity.KEY_PARAMS, info);
        startActivityForResult(intent, data.type == BasePrintInfo.USB_PRINT ? PrintSettingActivity.
                REQUEST_CODE_PRINT_SETTING_USB : PrintSettingActivity.REQUESTcODE_PRINT_SETTING_NET);
    }

    @Override
    public void onLongPrintListItemClick(int position, BasePrintInfo data) {
        if (null==reminderFragment){
            reminderFragment = ReminderFragment.getInstance("确定删除?");
        }
        reminderFragment.setReminderListener(()->{
            if (data instanceof NetPrintInfo){
                if (mNetPrintInfos.contains(data)){
                    mNetPrintInfos.remove(data);
                    mNetAdapter.notifyItemRemoved(position);
                    PrintReceiptsUtil.removeNetPrint((NetPrintInfo) data);
                }
            } else if (data instanceof UsbPrintInfo){
                if (mUsbPrintInfos.contains(data)){
                    mUsbPrintInfos.remove(data);
                    mUsbAdapter.notifyItemRemoved(position);
                    PrintReceiptsUtil.removeUsbPrint((UsbPrintInfo) data);
                }
            }
        });
        reminderFragment.show(getChildFragmentManager(),"reminderFragment");
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != Activity.RESULT_OK) return;
        switch (requestCode) {
            case PrintSettingActivity.REQUEST_CODE_PRINT_SETTING_USB:
                Log.e("onActivityResult","usb");
                if (clickPosition == -1 || clickPosition >= mUsbPrintInfos.size()) {
                    clickPosition = -1;
                    return;
                }
                Log.e("onActivityResult","usb1");
                if (null != data) {
                    Log.e("onActivityResult","usb2");
                    UsbPrintInfo info = mUsbPrintInfos.get(clickPosition);
                    UsbPrintInfo returnInfo = (UsbPrintInfo) data.getSerializableExtra(PrintSettingActivity.KEY_RETURN_INFO);
                    PrintReceiptsUtil.setPrintInfoData(info, returnInfo);
                    mUsbAdapter.notifyItemChanged(clickPosition);
                    clickPosition = -1;
                }
                break;
            case PrintSettingActivity.REQUESTcODE_PRINT_SETTING_NET:
                Log.e("onActivityResult","net");
                if (clickPosition == -1 || clickPosition >= mNetPrintInfos.size()) {
                    clickPosition = -1;
                    return;
                }
                if (null != data) {
                    NetPrintInfo info = mNetPrintInfos.get(clickPosition);
                    NetPrintInfo returnInfo = (NetPrintInfo) data.getSerializableExtra(PrintSettingActivity.KEY_RETURN_INFO);
                    PrintReceiptsUtil.setPrintInfoData(info, returnInfo);
                    mNetAdapter.notifyItemChanged(clickPosition);
                    PrintReceiptsUtil.setNetPrint(info);
                    clickPosition = -1;
                }
                break;
        }
    }
}
